package com.tuniu.agents.config;

import reactor.core.publisher.Flux;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;

/**
 * Stream Processor Interface
 * Defines the basic behavior of stream processing
 */
public interface StreamProcessor {

    /**
     * Content Wrapper Configuration Class, used to configure the prefix and suffix for extracted content
     */
    class ContentWrapper {
        private String prefix = "";
        private String suffix = "";

        public ContentWrapper() {}

        public ContentWrapper(String prefix, String suffix) {
            this.prefix = prefix;
            this.suffix = suffix;
        }

        /**
         * Wraps the content with the specified prefix and suffix
         * @param content The content to be wrapped
         * @return Wrapped content
         */
        public String wrap(String content) {
            return prefix + content + suffix;
        }
    }

    /**
     * Extraction Result Class, contains the extracted content and the processed length
     */
    class ExtractResult {
        // Changed to protected access level
        protected List<String> extractedContents = new ArrayList<>();
        private int processedLength = 0;

        public void addExtractedContent(String content) {
            extractedContents.add(content);
        }

        public List<String> getExtractedContents() {
            return extractedContents;
        }

        public void setExtractedContents(List<String> contents) {
            this.extractedContents = new ArrayList<>(contents);
        }

        public boolean hasExtracted() {
            return !extractedContents.isEmpty();
        }

        public void setProcessedLength(int length) {
            this.processedLength = length;
        }

        public int getProcessedLength() {
            return processedLength;
        }

        public void ensureCapacity(int capacity) {
            if (extractedContents instanceof ArrayList) {
                ((ArrayList<String>) extractedContents).ensureCapacity(capacity);
            }
        }
    }

    /**
     * Processes the stream using custom extraction logic
     * @param flux Input stream
     * @param extractor Content extraction function that receives accumulated content and returns extraction result
     * @return Processed stream
     */
    Flux<String> process(Flux<String> flux, Function<String, ExtractResult> extractor);

    /**
     * Processes the captured content
     * @param content Captured content
     * @return Processed content
     */
    default String processCapturedContent(String content) {
        return content;
    }
}